package com.example.vault.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.Arrays;
import java.util.List;

/**
 * Redis集群配置
 * 从Vault动态获取Redis集群连接凭据
 */
@Configuration
public class RedisConfig {

    // Redis集群节点配置（从Vault获取）
    @Value("${redis.cluster.nodes:127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002}")
    private String clusterNodes;

    // Redis认证密码（从Vault获取）
    @Value("${redis.cluster.password:}")
    private String password;

    // Redis连接超时时间
    @Value("${redis.cluster.timeout:5000}")
    private int timeout;

    // Redis最大重定向次数
    @Value("${redis.cluster.max-redirects:3}")
    private int maxRedirects;

    // 连接池配置
    @Value("${redis.cluster.pool.max-active:200}")
    private int maxActive;

    @Value("${redis.cluster.pool.max-idle:20}")
    private int maxIdle;

    @Value("${redis.cluster.pool.min-idle:5}")
    private int minIdle;

    @Value("${redis.cluster.pool.max-wait:3000}")
    private long maxWait;

    /**
     * Redis集群配置
     */
    @Bean
    public RedisClusterConfiguration redisClusterConfiguration() {
        RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration();
        
        // 解析集群节点
        List<String> nodes = Arrays.asList(clusterNodes.split(","));
        clusterConfig.setClusterNodes(nodes.stream()
            .map(node -> {
                String[] parts = node.trim().split(":");
                return new org.springframework.data.redis.connection.RedisNode(parts[0], Integer.parseInt(parts[1]));
            })
            .collect(java.util.stream.Collectors.toList()));
        
        // 设置密码（如果有）
        if (password != null && !password.trim().isEmpty()) {
            clusterConfig.setPassword(RedisPassword.of(password));
        }
        
        // 设置最大重定向次数
        clusterConfig.setMaxRedirects(maxRedirects);
        
        return clusterConfig;
    }

    /**
     * Redis连接工厂
     */
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory factory = new JedisConnectionFactory(redisClusterConfiguration());
        
        // 设置连接池配置
        factory.getPoolConfig().setMaxTotal(maxActive);
        factory.getPoolConfig().setMaxIdle(maxIdle);
        factory.getPoolConfig().setMinIdle(minIdle);
        factory.getPoolConfig().setMaxWaitMillis(maxWait);
        
        // 设置连接超时
        factory.setTimeout(timeout);
        
        return factory;
    }

    /**
     * Redis模板配置
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory());
        
        // 设置序列化器
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
        
        // Key序列化
        template.setKeySerializer(stringSerializer);
        template.setHashKeySerializer(stringSerializer);
        
        // Value序列化
        template.setValueSerializer(jsonSerializer);
        template.setHashValueSerializer(jsonSerializer);
        
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 字符串Redis模板
     */
    @Bean
    public RedisTemplate<String, String> stringRedisTemplate() {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory());
        
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringSerializer);
        template.setValueSerializer(stringSerializer);
        template.setHashKeySerializer(stringSerializer);
        template.setHashValueSerializer(stringSerializer);
        
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 缓存Redis模板（用于支付系统缓存）
     */
    @Bean("cacheRedisTemplate")
    public RedisTemplate<String, Object> cacheRedisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory());
        
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
        
        // 设置Key前缀
        template.setKeySerializer(new StringRedisSerializer() {
            @Override
            public byte[] serialize(String string) {
                return super.serialize("payment:cache:" + string);
            }
        });
        
        template.setHashKeySerializer(stringSerializer);
        template.setValueSerializer(jsonSerializer);
        template.setHashValueSerializer(jsonSerializer);
        
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 会话Redis模板（用于用户会话管理）
     */
    @Bean("sessionRedisTemplate")
    public RedisTemplate<String, Object> sessionRedisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory());
        
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
        
        // 设置Key前缀
        template.setKeySerializer(new StringRedisSerializer() {
            @Override
            public byte[] serialize(String string) {
                return super.serialize("payment:session:" + string);
            }
        });
        
        template.setHashKeySerializer(stringSerializer);
        template.setValueSerializer(jsonSerializer);
        template.setHashValueSerializer(jsonSerializer);
        
        template.afterPropertiesSet();
        return template;
    }

    /**
     * 分布式锁Redis模板
     */
    @Bean("lockRedisTemplate")
    public RedisTemplate<String, String> lockRedisTemplate() {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory());
        
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        
        // 设置Key前缀
        template.setKeySerializer(new StringRedisSerializer() {
            @Override
            public byte[] serialize(String string) {
                return super.serialize("payment:lock:" + string);
            }
        });
        
        template.setValueSerializer(stringSerializer);
        template.setHashKeySerializer(stringSerializer);
        template.setHashValueSerializer(stringSerializer);
        
        template.afterPropertiesSet();
        return template;
    }
}